package com.glorystone.ins.service.impl;

import com.glorystone.ins.service.CaculateService;
import com.glorystone.ins.vo.RebateVO;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * 计算税后保费，渠道返点
 * Created by wangwei on 2018/3/20.
 */
@Service
public class CaculateServiceImpl implements CaculateService{


    /**
     * 1.补点开票形式为现金 公式：
     *        1*跟单点位/{(1+价税分离税点)*(1+开票税点)} + 1*补点点位/(1+价税分离税点)-所选产品的自留点位
     *
     *
     * 2. 补点开票形式为三方开票
     *          1*跟单点位/{(1+价税分离税点)*(1+开票税点)} + 1*补点点位/(1+价税分离税点)*开票比例-所选产品的自留点位
     * @return 计算值
     */
    @Override
    public BigDecimal calcRebateRate(RebateVO rebateVO) {


        if (rebateVO.getType() == RebateVO.TypeEnum.CASH.getValue()) {
            return cashRate(rebateVO).multiply(BigDecimal.valueOf(100));

        } else if (rebateVO.getType() == RebateVO.TypeEnum.TRIPLE_TICKET.getValue()) {

            return tripleTicketRate(rebateVO).multiply(BigDecimal.valueOf(100));
        }

        return null;

    }

    /**
     * 现金形式
     * 1*跟单点位/{(1+价税分离税点)*(1+开票税点)} + 1*补点点位/(1+价税分离税点)-所选产品的自留点位
     * @param rebateVO
     * @return
     */
    private BigDecimal cashRate(RebateVO rebateVO) {
        boolean isPercent = rebateVO.getPercent();
        if (isPercent) {
            convertData(rebateVO);
        }
        // (1+价税分离税点)*(1+开票税点)
        BigDecimal v1 = BigDecimal.valueOf(1).add(rebateVO.getSeparatePoint()).multiply(BigDecimal.valueOf(1).add(rebateVO.getTicketTaxPoint()));
        // 1*跟单点位/{(1+价税分离税点)*(1+开票税点)}
        BigDecimal v2 = BigDecimal.valueOf(1).multiply(rebateVO.getFollowTicketPoint()).divide(v1, 4, BigDecimal.ROUND_HALF_UP);

        // 1*补点点位/(1+价税分离税点)
        BigDecimal v3 = BigDecimal.valueOf(1).multiply(rebateVO.getSupplementPoint()).divide(BigDecimal.valueOf(1).add(rebateVO.getSeparatePoint()), 4, BigDecimal.ROUND_HALF_UP);

        return v2.add(v3).subtract(rebateVO.getSelfPoint());

    }

    private void convertData(RebateVO rebateVO) {

        rebateVO.setFollowTicketPoint(getActual(rebateVO.getFollowTicketPoint()));
        rebateVO.setSeparatePoint(getActual(rebateVO.getSeparatePoint()));
        rebateVO.setTicketTaxPoint(getActual(rebateVO.getTicketTaxPoint()));
        rebateVO.setSupplementPoint(getActual(rebateVO.getSupplementPoint()));
        rebateVO.setTicketRate(getActual(rebateVO.getTicketRate()));
        rebateVO.setSelfPoint(getActual(rebateVO.getSelfPoint()));
    }


    private BigDecimal getActual(BigDecimal n) {
        return n.divide(BigDecimal.valueOf(100), 6, BigDecimal.ROUND_HALF_UP);
    }


    /**
     * 三方开票形式
     * 1*跟单点位/{(1+价税分离税点)*(1+开票税点)} + 1*补点点位/(1+价税分离税点)*开票比例-所选产品的自留点位
     * @param rebateVO
     * @return
     */

    private BigDecimal tripleTicketRate(RebateVO rebateVO) {

        boolean isPercent = rebateVO.getPercent();
        if (isPercent) {
            convertData(rebateVO);
        }


        // (1+价税分离税点)*(1+开票税点)
        BigDecimal v1 = BigDecimal.valueOf(1).add(rebateVO.getSeparatePoint()).multiply(BigDecimal.valueOf(1).add(rebateVO.getTicketTaxPoint()));
        // 1*跟单点位/{(1+价税分离税点)*(1+开票税点)}
        BigDecimal v2 = BigDecimal.valueOf(1).multiply(rebateVO.getFollowTicketPoint()).divide(v1, 4, BigDecimal.ROUND_HALF_UP);

        // 1*补点点位/(1+价税分离税点)*开票比例
        BigDecimal v3 = BigDecimal.valueOf(1).multiply(rebateVO.getSupplementPoint()).divide(BigDecimal.valueOf(1).add(rebateVO.getSeparatePoint()), 4, BigDecimal.ROUND_HALF_UP).multiply(rebateVO.getTicketRate());
        BigDecimal number = v2.add(v3).subtract(rebateVO.getSelfPoint());
        BigDecimal decimal = number.setScale(4, BigDecimal.ROUND_HALF_UP);
        return decimal;
    }

    @Override
    public BigDecimal calcFeeAfterTax(BigDecimal feeAmount, BigDecimal separateRate, boolean isPercent) {
        BigDecimal temp;
        if (isPercent) {
            temp = separateRate.divide(BigDecimal.valueOf(100), 6, BigDecimal.ROUND_HALF_UP);
            temp = temp.add(BigDecimal.valueOf(1));

        } else {
            temp = separateRate.add(BigDecimal.valueOf(1));

        }

        return feeAmount.divide(temp, 2, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 计算税后保费
     * 税后保费公式为：全保费/（1+价税分离税点）
     *
     * @param feeAmount 全保费
     * @param separateRate 价税分离税点
     * @return 四舍五入结果
     */
    @Override
    public BigDecimal calcFeeAfterTax(BigDecimal feeAmount, BigDecimal separateRate) {
       return calcFeeAfterTax(feeAmount, separateRate, true);
    }


    public static void main(String[] args) {
        BigDecimal bigDecimal = new BigDecimal("10.8467");
        BigDecimal decimal = bigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP);
        System.out.println(decimal);
    }
}
